package com.java80.littlegame.common.base;

import java.util.Map.Entry;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.hazelcast.core.EntryEvent;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.IMap;
import com.hazelcast.core.Member;
import com.hazelcast.core.MemberAttributeEvent;
import com.hazelcast.core.MembershipEvent;
import com.hazelcast.core.MembershipListener;
import com.hazelcast.map.listener.EntryAddedListener;

import io.vertx.core.AbstractVerticle;
import io.vertx.core.DeploymentOptions;
import io.vertx.core.eventbus.EventBus;

public abstract class BaseVerticle extends AbstractVerticle {
	final transient static Logger log = LoggerFactory.getLogger(BaseVerticle.class);

	@Override
	public void start() throws Exception {
		super.start();
		SystemDataMgr.loadSystemData();
		EventBus eventBus = vertx.eventBus();
		vertx.deployVerticle(VertxMessageHelper.class, new DeploymentOptions().setWorker(true).setInstances(3));
		// eventBus.registerDefaultCodec(BaseMsg.class, new VertxMsgCodec());
		String queueName = queueName();
		if (StringUtils.isNotBlank(queueName)) {
			eventBus.consumer(queueName, msg -> {
				String json = msg.body().toString();
				log.info("收到来自集群的消息：->{}", json);
				BaseHandler.addTask(getHandler(), json);
			});
		}

		if (needPublishServiceStatus()) {
			publishService();
		}
	}

	protected void publishService() {
		String ServiceStatusMapName = "ServiceStatusMap";
		// 发布服务信息
		ServiceStatus ss = getServiceStatus();
		HazelcastInstance ins = Hazelcast.getHazelcastInstanceByName(ss.getInstanceName());
		// 获取其他服务的信息缓存到本地
		IMap<String, ServiceStatus> map = ins.getMap(ServiceStatusMapName);
		Set<Member> members = ins.getCluster().getMembers();
		for (Member member : members) {
			if (member.localMember()) {
				// 发布本节点
				map.put(member.getUuid(), getServiceStatus());
			} else {
				// 读取其他节点
				Set<Entry<String, ServiceStatus>> entrySet = map.entrySet();
				for (Entry<String, ServiceStatus> entry : entrySet) {
					ServiceStatusHelper.addServiceStatus(entry.getValue());
				}

			}
		}
		map.addEntryListener(new EntryAddedListener<String, ServiceStatus>() {
			@Override
			public void entryAdded(EntryEvent<String, ServiceStatus> event) {
				// 监听其他节点加入
				ServiceStatus value = event.getValue();
				ServiceStatusHelper.addServiceStatus(value);
			}

		}, true);
		ins.getCluster().addMembershipListener(new MembershipListener() {

			@Override
			public void memberRemoved(MembershipEvent membershipEvent) {
				if (!membershipEvent.getMember().localMember()) {
					Member member = membershipEvent.getMember();
					log.info("集群中节点关闭！" + member);
					ServiceStatus remove = map.remove(membershipEvent.getMember().getUuid());
					ServiceStatusHelper.removeServiceStatus(remove.getServiceId());
				}
			}

			@Override
			public void memberAttributeChanged(MemberAttributeEvent memberAttributeEvent) {
			}

			@Override
			public void memberAdded(MembershipEvent membershipEvent) {
			}
		});

	}

	@Override
	public void stop() throws Exception {
		super.stop();

	}

	public abstract String queueName();

	public abstract BaseHandler getHandler();

	public abstract ServiceStatus getServiceStatus();

	public abstract boolean needPublishServiceStatus();
}
